from operator import itemgetter
def analysis_flow_coflict(cluster_size, whether_hd):
    if(whether_hd == False):
        flow_route_of_leaf = {} #key:(src,dst), value:[(switch_id,eth_id), ....]
        flow_in_leaf = {} #key:(switch_id,eth_id), value:[ (src,dst), ....]
        with open(str(cluster_size)+'flow_in_leaf.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                if (strlist[0], strlist[1]) not in flow_route_of_leaf:
                    flow_route_of_leaf[(strlist[0], strlist[1])] = []
                flow_route_of_leaf[(strlist[0], strlist[1])].append((strlist[2], strlist[3]))
                if (strlist[2], strlist[3]) not in flow_in_leaf:
                    flow_in_leaf[(strlist[2], strlist[3])] = []
                flow_in_leaf[(strlist[2], strlist[3])].append((strlist[0], strlist[1]))
        print("leaf conflict:")
        print(flow_in_leaf)
        flow_route_of_spine = {} #key:(src,dst), value:[(switch_id,eth_id), ....]
        flow_in_spine = {} #key:(switch_id,eth_id), value:[ (src,dst), ....]
        with open(str(cluster_size)+'flow_in_spine.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                if (strlist[0], strlist[1]) not in flow_route_of_spine:
                    flow_route_of_spine[(strlist[0], strlist[1])] = []
                flow_route_of_spine[(strlist[0], strlist[1])].append((strlist[2], strlist[3]))
                if (strlist[2], strlist[3]) not in flow_in_spine:
                    flow_in_spine[(strlist[2], strlist[3])] = []
                flow_in_spine[(strlist[2], strlist[3])].append((strlist[0], strlist[1]))
        print("spine conflict:")
        print(conflict_flow_distribution(flow_in_spine))
        print("conflict_detail")
        for key, value in flow_route_of_spine.items():
            print(key,value)
        analysis_flow_conflict_with_what(flow_route_of_leaf, flow_route_of_spine, cluster_size, whether_hd)
        return flow_route_of_leaf, flow_in_leaf, flow_route_of_spine, flow_in_spine


    else:
        flow_route_of_leaf = {} #key:(src,dst), value:[(switch_id,eth_id), ....]
        flow_in_leaf = {} #key:(switch_id,eth_id), value:[ (src,dst), ....]
        with open(str(cluster_size)+'flow_in_leaf_hd.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                if (strlist[0], strlist[1]) not in flow_route_of_leaf:
                    flow_route_of_leaf[(strlist[0], strlist[1])] = []
                flow_route_of_leaf[(strlist[0], strlist[1])].append((strlist[2], strlist[3]))
                if (strlist[2], strlist[3]) not in flow_in_leaf:
                    flow_in_leaf[(strlist[2], strlist[3])] = []
                flow_in_leaf[(strlist[2], strlist[3])].append((strlist[0], strlist[1]))
        # print("leaf conflict:")
        # for key, value in flow_in_leaf.items():
        #     print(key,value)
        # print(conflict_flow_distribution(flow_in_leaf))
        flow_route_of_spine = {} #key:(src,dst), value:[(switch_id,eth_id), ....]
        flow_in_spine = {} #key:(switch_id,eth_id), value:[ (src,dst), ....]
        with open(str(cluster_size)+'flow_in_spine_hd.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                if (strlist[0], strlist[1]) not in flow_route_of_spine:
                    flow_route_of_spine[(strlist[0], strlist[1])] = []
                flow_route_of_spine[(strlist[0], strlist[1])].append((strlist[2], strlist[3]))
                if (strlist[2], strlist[3]) not in flow_in_spine:
                    flow_in_spine[(strlist[2], strlist[3])] = []
                flow_in_spine[(strlist[2], strlist[3])].append((strlist[0], strlist[1]))
        # print("spine conflict:")
        # for key, value in flow_in_spine.items():
        #     print(key,value)
        # print(conflict_flow_distribution(flow_in_spine))
        analysis_flow_conflict_with_what(flow_route_of_leaf, flow_route_of_spine, cluster_size, whether_hd)
        return flow_route_of_leaf, flow_in_leaf, flow_route_of_spine, flow_in_spine

def analysis_flow_conflict_with_what(flow_route_of_leaf, flow_route_of_spine, cluster_size, whether_hd):
    flow_finishtime = {}
    flow_start_time = {}
    if(whether_hd == False):
        with open(str(cluster_size)+'result_ECN1000000000.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                #flow_finishtime[(str(int(strlist[0])-1), str(int(strlist[1])-1))]=strlist[2]
                if(int((int(strlist[0])-1)/8) !=int((int(strlist[1])-1)/8)):
                    flow_finishtime[(strlist[0], strlist[1])]=float(strlist[2])
    else:
        with open(str(cluster_size)+'resulthd_ECN1000000000.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                #flow_finishtime[(str(int(strlist[0])-1), str(int(strlist[1])-1))]=strlist[2]
                if(int((int(strlist[0])-1)/8) !=int((int(strlist[1])-1)/8)):
                    flow_finishtime[(strlist[0], strlist[1])]=float(strlist[2])
                    #print(strlist[0],strlist[1],strlist[2])
    if(whether_hd == False):
        with open(str(cluster_size)+'start_ECN1000000000.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                #flow_start_time[(str(int(strlist[0])-1), str(int(strlist[1])-1))]=strlist[2]
                if(int((int(strlist[0])-1)/8) !=int((int(strlist[1])-1)/8)):
                    flow_start_time[(strlist[0], strlist[1])]=float(strlist[2])
    else:
        with open(str(cluster_size)+'starthd_ECN1000000000.txt', 'r',encoding='utf-8') as f:
            for line in f.readlines():
                line=line.rstrip("\n")
                strlist = line.split('-')
                #flow_start_time[(str(int(strlist[0])-1), str(int(strlist[1])-1))]=strlist[2]
                if(int((int(strlist[0])-1)/8) !=int((int(strlist[1])-1)/8)):
                    flow_start_time[(strlist[0], strlist[1])]=float(strlist[2])
                    #print(strlist[0],strlist[1],strlist[2])
    print("leaf conflict detail")
    for key, value in flow_route_of_leaf.items():
        if key in flow_start_time and key in flow_finishtime:
            print(key[0]+'-'+key[1],value, flow_start_time[key], flow_finishtime[key])
        elif key in flow_start_time:
            print(key[0]+'-'+key[1],value, flow_start_time[key])
    print("spine conflict detail")
    for key, value in flow_route_of_spine.items():
        if key in flow_start_time and key in flow_finishtime:
            print(key[0]+'-'+key[1],value, flow_start_time[key], flow_finishtime[key])
        elif key in flow_start_time:
            print(key[0]+'-'+key[1],value, flow_start_time[key])

    flow_conflict_with_what = {}
    flow_conflict_num_timeline = {}
    for key, value in flow_route_of_leaf.items(): 
        if key in flow_finishtime:
            if key not in flow_conflict_with_what:
                flow_conflict_with_what[key] = set([])
            if key not in flow_conflict_num_timeline:
                flow_conflict_num_timeline[key] = [[flow_start_time[key], 1],[flow_finishtime[key], 1]]
            for key2, value2 in flow_route_of_leaf.items(): 
                if key2 in flow_finishtime and key2 not in flow_conflict_with_what[key]:
                    set_c = set(value) & set(value2)
                    list_c = list(set_c)
                    if(len(list_c) >=1 and key[0]!=key2[0] and key[1]!=key2[1] and flow_start_time[key]<flow_finishtime[key2]  and flow_start_time[key2]<flow_finishtime[key]):
                        flow_conflict_with_what[key].add(key2)

                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if time_conflict_num_item[0] <= flow_finishtime[key2] and time_conflict_num_item[0] >= flow_start_time[key2]:
                                time_conflict_num_item[1] = time_conflict_num_item[1] + 1
                        insert_start_time,insert_finish_time = False, False
                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if not insert_start_time and time_conflict_num_item[0] <= flow_start_time[key2]:
                                flow_conflict_num_timeline[key].append([flow_start_time[key2], time_conflict_num_item[1]+1 ])
                                insert_start_time = True
                            if not insert_finish_time and time_conflict_num_item[0] >= flow_finishtime[key2]:
                                flow_conflict_num_timeline[key].append([flow_finishtime[key2], time_conflict_num_item[1]+1 ])
                                insert_finish_time = True
                        flow_conflict_num_timeline[key].sort(key=itemgetter(0,1))
                elif key2 in flow_start_time and key2 not in flow_conflict_with_what[key]:
                    set_c = set(value) & set(value2)
                    list_c = list(set_c)
                    if(len(list_c) >=1 and key[0]!=key2[0] and key[1]!=key2[1] and flow_start_time[key2]<flow_finishtime[key]):
                        flow_conflict_with_what[key].add(key2)

                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if  time_conflict_num_item[0] >= flow_start_time[key2]:
                                time_conflict_num_item[1] = time_conflict_num_item[1] + 1
                        insert_start_time,insert_finish_time = False, False
                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if not insert_start_time and time_conflict_num_item[0] <= flow_start_time[key2]:
                                flow_conflict_num_timeline[key].append([flow_start_time[key2], time_conflict_num_item[1]+1 ])
                                insert_start_time = True
                            if not insert_finish_time:
                                flow_conflict_num_timeline[key].append([time_conflict_num_item[0], time_conflict_num_item[1]+1 ])
                                insert_finish_time = True
                        flow_conflict_num_timeline[key].sort(key=itemgetter(0,1))
                            
    for key, value in flow_route_of_spine.items(): 
        if key in flow_finishtime:
            if key not in flow_conflict_with_what:
                flow_conflict_with_what[key] = set([])
            if key not in flow_conflict_num_timeline:
                flow_conflict_num_timeline[key] = [[flow_start_time[key], 1],[flow_finishtime[key], 1]]
            for key2, value2 in flow_route_of_spine.items(): 
                if key2 in flow_finishtime and key2 not in flow_conflict_with_what[key]:
                    set_c = set(value) & set(value2)
                    list_c = list(set_c)
                    if(len(list_c) >=1 and key[0]!=key2[0] and key[1]!=key2[1] and flow_start_time[key]<flow_finishtime[key2]  and flow_start_time[key2]<flow_finishtime[key]):
                        flow_conflict_with_what[key].add(key2)

                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if time_conflict_num_item[0] <= flow_finishtime[key2] and time_conflict_num_item[0] >= flow_start_time[key2]:
                                time_conflict_num_item[1] = time_conflict_num_item[1] + 1
                        insert_start_time,insert_finish_time = False, False
                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if not insert_start_time and time_conflict_num_item[0] <= flow_start_time[key2]:
                                flow_conflict_num_timeline[key].append([flow_start_time[key2], time_conflict_num_item[1]+1 ])
                                insert_start_time = True
                            if not insert_finish_time and time_conflict_num_item[0] >= flow_finishtime[key2]:
                                flow_conflict_num_timeline[key].append([flow_finishtime[key2], time_conflict_num_item[1]+1 ])
                                insert_finish_time = True
                        flow_conflict_num_timeline[key].sort(key=itemgetter(0,1))

                elif key2 in flow_start_time and key2 not in flow_conflict_with_what[key]:
                    set_c = set(value) & set(value2)
                    list_c = list(set_c)
                    if(len(list_c) >=1 and key[0]!=key2[0] and key[1]!=key2[1] and flow_start_time[key2]<flow_finishtime[key]):
                        flow_conflict_with_what[key].add(key2)

                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if  time_conflict_num_item[0] >= flow_start_time[key2]:
                                time_conflict_num_item[1] = time_conflict_num_item[1] + 1
                        insert_start_time,insert_finish_time = False, False
                        for time_conflict_num_item in flow_conflict_num_timeline[key]:
                            if not insert_start_time and time_conflict_num_item[0] <= flow_start_time[key2]:
                                flow_conflict_num_timeline[key].append([flow_start_time[key2], time_conflict_num_item[1]+1 ])
                                insert_start_time = True
                            if not insert_finish_time:
                                flow_conflict_num_timeline[key].append([time_conflict_num_item[0], time_conflict_num_item[1]+1 ])
                                insert_finish_time = True
                        flow_conflict_num_timeline[key].sort(key=itemgetter(0,1))

    for key,value in flow_conflict_num_timeline.items():
        print(key[0]+'-'+key[1])
        time_list = []
        rate_list = []
        for item in value:
            time_list.append(item[0])
            rate_list.append(100000/item[1])
        print("t2=",end='')
        print(time_list)
        print("z5=",end='')
        print(rate_list)
    # for key,value in flow_conflict_with_what.items():
    #     print(key,end=": ")
    #     print(value)
    return flow_conflict_with_what

def check_conflict_flow_num(flow_in_switch, switch_id, eth_id):
    return len(flow_in_switch[(switch_id, eth_id)])

def conflict_flow_distribution(flow_in_switch):
    conflict_flow_num = {}
    for key, value in flow_in_switch.items():
        new_key = len(value)
        if new_key not in conflict_flow_num:
            conflict_flow_num[new_key] = 0
        conflict_flow_num[new_key] = conflict_flow_num[new_key]+1
    return conflict_flow_num

analysis_flow_coflict(64, True)
